package com.gamex.battle.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import com.gamex.battle.common.Constants;

@Component
public class BattleServer implements InitializingBean, DisposableBean{
	private static final Logger logger = Logger.getLogger(BattleServer.class.getName());
	 
	private int port;
	ServerBootstrap b = null;
    ChannelFuture f = null;
    NioEventLoopGroup loopGroup1 = new NioEventLoopGroup();
    NioEventLoopGroup loopGroup2 = new NioEventLoopGroup();
    
	public BattleServer() {}

	public BattleServer(int port) {
        this.port = port;
    }
    
    public void run() throws InterruptedException {
        
        try {
        	b = new ServerBootstrap();
            b.group(loopGroup1, loopGroup2)
             .channel(NioServerSocketChannel.class)
             .localAddress(port)
             .childHandler(new ChannelInitializer<SocketChannel>() {
	            @Override
	            public void initChannel(SocketChannel ch) throws Exception {
	                ch.pipeline().addLast(
	                        new ObjectEncoder(),
	                        new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
	                        new BattleServerHandler());
	            }
             });

         	
            //b.bind().sync().channel().closeFuture().sync();
              b.bind().sync();
        }catch (Exception e) {
        	logger.log(Level.INFO,"Battle server failed to start....... [" + e.getMessage() + "]");
		} finally {}
        
    }


	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("==========================================");
		System.out.println("battle-socket-server has been started.....");
		System.out.println("==========================================");
	      new BattleServer(Constants.SERVER_PORT).run();
	}

	@Override
	public void destroy() throws Exception {
		System.out.println("==========================================");
		System.out.println("battle-socket-server is shutdown..........");
		System.out.println("==========================================");
		f.channel().closeFuture().sync();
		b.shutdown();
		loopGroup1.shutdown();
		loopGroup2.shutdown();
	}
}